package com.company.project.service.impl;

import com.company.project.entity.*;
import com.company.project.mapper.RptAnnualReportMapper;
import com.company.project.mapper.RptApprovalReportMapper;
import com.company.project.mapper.RptMatchingReportMapper;
import com.company.project.service.RptMatchingReportService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class RptMatchingReportServiceImpl implements RptMatchingReportService {

    @Autowired
    private RptMatchingReportMapper rptMatchingReportMapper;

    @Autowired
    private RptAnnualReportMapper rptAnnualReportMapper;

    @Autowired
    private RptApprovalReportMapper rptApprovalReportMapper;

    /**
     * 查询匹配成功的企业并标记为匹配成功
     *
     * @return
     */
    @Override
    public Integer findMatchingReportByDominationAndAddress() {
        List<RptAnnualReportEntity> matchingList = rptMatchingReportMapper.findMatchingReportByDominationAndAddress();
        // 在工商表中标记已匹配
        for (RptAnnualReportEntity rptAnnualReportEntity : matchingList) {
            rptAnnualReportEntity.setMatching(1);
            rptAnnualReportMapper.updateAnnualReport(rptAnnualReportEntity);
        }
        Integer integer = 0;
        if (matchingList.size() != 0) {
            // 更新数据
            integer = changeReportMatchingDataBase(matchingList, 1,1);
            if (integer == 0) {
                throw new RuntimeException("数据库更新失败 !!!");
            }
        }

        return integer;
    }

    /**
     * 查询匹配未成功的企业并标记为匹配失败
     *
     * @return
     */
    @Override
    public Integer findNotMatchingReportByDominationAndAddress() {
        List<RptAnnualReportEntity> notMatchingList = rptMatchingReportMapper.findNotMatchingReportByDominationAndAddress();
        List<RptAnnualReportEntity> confirmList = new ArrayList<>();
        List<RptAnnualReportEntity> notConfirmList = new ArrayList<>();
        // 在工商表中标记已匹配
        for (RptAnnualReportEntity rptAnnualReportEntity : notMatchingList) {
            rptAnnualReportEntity.setMatching(1);
            rptAnnualReportMapper.updateAnnualReport(rptAnnualReportEntity);
            RptMatchingConfirmReportEntity obj = rptMatchingReportMapper.findMatchingConfirmByMatchingReport(rptAnnualReportEntity);
            if (obj != null) {
                confirmList.add(rptAnnualReportEntity);
            } else {
                notConfirmList.add(rptAnnualReportEntity);
            }
        }

        if (notMatchingList.size() != 0) {
            // 更新数据
            changeReportMatchingDataBase(confirmList, 1,1);
            changeReportMatchingDataBase(notConfirmList, 2, 2);
        }
        return 1;
    }

    /**
     * 查询匹配报表
     * @param rptMatchingReportEntity
     * @return
     */
    @Override
    public PageInfo<RptMatchingReportEntity> pageInfo(RptMatchingReportEntity rptMatchingReportEntity) {
        PageHelper.startPage(rptMatchingReportEntity.getPage(),rptMatchingReportEntity.getLimit());
        List<RptMatchingReportEntity> list = rptMatchingReportMapper.findAllMatchingReport(rptMatchingReportEntity);
        PageInfo<RptMatchingReportEntity> pageInfo = new PageInfo<>(list);
        return pageInfo;
    }

    /**
     * 手动修改匹配失败的信息，将失败改成成功，并且存入到rpt_matching_confirm_report中
     * @param rptMatchingReportEntity
     * @return
     */
    @Override
    public Integer addMatchingFailToSuccess(RptMatchingReportEntity rptMatchingReportEntity) {
        Integer integer = rptMatchingReportMapper.addMatchingFailToSuccess(rptMatchingReportEntity);
        if (integer == 0) {
            return integer;
        }
        // 更改rpt_matching_report中的匹配结果状态和确认状态
        rptMatchingReportEntity.setMatchingResult(1);
        rptMatchingReportEntity.setConfirmStatus(1);
        Integer report = rptMatchingReportMapper.updateMatchingReport(rptMatchingReportEntity);
        if (report == 0) {
            return report;
        }
        return 1;
    }

    /**
     * 根据id查询某条匹配信息
     * @param id
     * @return
     */
    @Override
    public RptMatchingReportEntity findMatchingReportById(Integer id) {
        return rptMatchingReportMapper.findMatchingReportById(id);
    }

    /**
     * 查找匹配度高的地址
     * @param id
     * @return
     */
    @Override
    public List<RptMatchingReportEntity> findHighMatchingAddress(Integer id) {
        RptMatchingReportEntity obj = rptMatchingReportMapper.findMatchingReportById(id);
        if (obj == null) {
            return null;
        }
        String domination = obj.getDomination();
        String street = obj.getAddress().split("四川")[1].split("街")[0];
        String address = obj.getAddress().split("四川")[1].split("街")[1];
        // 模糊查找相关的地址
        List<String> list = rptMatchingReportMapper.findHighMatchingAddress(domination,street,address);

        // 存放该匹配地址与相关度高的地址和相关度
        Map<String, Object> maps = new HashMap<>();
        // 存放相关度地址和相关度
        Map<String, Object> map = new HashMap<>();

        List<RptMatchingReportEntity> degreeList = new ArrayList<>();
        for (String s : list) {
            RptMatchingReportEntity rptMatchingReportEntity = new RptMatchingReportEntity();
            Double num = similarCalc(obj.getAddress(), s);
            if (num < 0.5) continue;
            // 将相关度地址与相关度以键值对的形式存入map中
            rptMatchingReportEntity.setAddress(s);
            rptMatchingReportEntity.setDegree(new DecimalFormat("###.##").format(num*100) + "%");
            degreeList.add(rptMatchingReportEntity);
        }
        return degreeList;
    }

    @Override
    public PageInfo<RptMatchingHistoryReportEntity> pageHistoryInfo(RptMatchingHistoryReportEntity rptMatchingHistoryReportEntity) {
        PageHelper.startPage(rptMatchingHistoryReportEntity.getPage(),rptMatchingHistoryReportEntity.getLimit());
        List<RptMatchingHistoryReportEntity> list = rptMatchingReportMapper.pageHistoryInfo(rptMatchingHistoryReportEntity);
        PageInfo<RptMatchingHistoryReportEntity> pageInfo = new PageInfo<>(list);
        return pageInfo;
    }

    /**
     * 编辑算法：计算两个字符串直接的相关度
     */
    private static int min(int one, int two, int three) {
        int min = one;
        if (two < min) min = two;
        if (three < min) min = three;
        return min;
    }

    public static int matrix(String s1, String s2) {
        int matrix[][];
        int n = s1.length();
        int m = s2.length();
        int i;
        int j;
        char c1;
        char c2;
        int temp;
        if (n == 0) return m;
        if (m == 0) return n;

        matrix = new int[n + 1][m + 1];
        for (i = 0; i <= n; i++) {
            matrix[i][0] = i;
        }

        for (j = 0; j <= m; j++) {
            matrix[0][j] = j;
        }

        for (i = 1; i <= n; i++) {
            c1 = s1.charAt(i - 1);

            for (j = 1; j <= m; j++) {
                c2 = s2.charAt(j - 1);
                if (c1 == c2) temp = 0;
                else temp = 1;

                matrix[i][j] = min(matrix[i - 1][j] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j - 1] + temp);
            }
        }

        return matrix[n][m];
    }

    public static double similarCalc(String s1, String s2) {
        int value = matrix(s1, s2);
        return 1 - (double) value / Math.max(s1.length(), s2.length());
    }

    /**
     * 自动在凌晨的时候将当天的匹配数据存入到历史表中
     */
    @Scheduled(cron = "0 59 23 * * ? ")
    public void autoSetMatchingReportToHistory(){
        // 查询当天所有的数据
        List<RptMatchingReportEntity> matchingList = rptMatchingReportMapper.findAllMatchingReport(new RptMatchingReportEntity());
        // 匹配表中存在当天的数据则存入到历史表中
        if (matchingList.size() != 0) {
            rptMatchingReportMapper.deleteMatchingReport();
            rptMatchingReportMapper.addBatchMatchingHistoryReport(matchingList);
        }
    }

    /**
     * 更改匹配表里的数据库信息（对匹配数据的新增或更新）
     * 参数：工商结果集合和匹配状态
     * @return
     */
    private Integer changeReportMatchingDataBase(List<RptAnnualReportEntity> list,Integer resultStatus,Integer confirmStatus){
        Integer result = 0;
        List<RptMatchingReportEntity> addList = new ArrayList<>();
        List<RptMatchingReportEntity> updateList = new ArrayList<>();
        // 根据信用代码查询是否该公司信息
        for (RptAnnualReportEntity rptAnnualReportEntity : list) {
            // 查询是否存在该信用代码的公司，若存在则更新信息，不存在则新增，并且判断时间是否一致
            RptMatchingReportEntity obj = rptMatchingReportMapper.findOneMatchingReportBySocialCreditCode(rptAnnualReportEntity.getSocialCreditCode(),
                    new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
//            RptApprovalReportEntity rptApprovalReportEntity = rptMatchingReportMapper.findApprovalByMatchingReport(obj);
            if (obj == null) {
                // 数据库在当前天没有该对象，则进行添加
                // 封装对象
                RptMatchingReportEntity rptMatchingReportEntity = getRptMatchingReportEntity(rptAnnualReportEntity);
                rptMatchingReportEntity.setMatchingResult(resultStatus);
                rptMatchingReportEntity.setConfirmStatus(confirmStatus);
                // 将数据添加到批量添加的集合当中
                addList.add(rptMatchingReportEntity);
            } else {
                // 数据库在当前天存在该对象，对该信息进行更新
                RptMatchingReportEntity rptMatchingReportEntity = getRptMatchingReportEntity(rptAnnualReportEntity);
                rptMatchingReportEntity.setId(obj.getId());
                rptMatchingReportEntity.setMatchingResult(resultStatus);
                rptMatchingReportEntity.setConfirmStatus(confirmStatus);
                // 将数据添加到批量更新的集合当中
                result = rptMatchingReportMapper.updateMatchingReport(rptMatchingReportEntity);
//                updateList.add(rptMatchingReportEntity);
            }
        }
        // 判断集合是否有数据，有则批量添加或是批量更新
        if (addList.size() != 0) {
            result = rptMatchingReportMapper.addBatchMatchingReport(addList);
        }
//        if (updateList.size() != 0) {
//            result = rptMatchingReportMapper.updateBatchMatchingReport(updateList);
//        }
        return result;
    }

    /**
     * 将工商对象里的值赋值给匹配对象
     * @param rptAnnualReportEntity
     * @return
     */
    private RptMatchingReportEntity getRptMatchingReportEntity(RptAnnualReportEntity rptAnnualReportEntity){
        RptMatchingReportEntity rptMatchingReportEntity = new RptMatchingReportEntity();
        rptMatchingReportEntity.setEnterpriseName(rptAnnualReportEntity.getEnterpriseName());
        rptMatchingReportEntity.setSocialCreditCode(rptAnnualReportEntity.getSocialCreditCode());
        rptMatchingReportEntity.setRegistrationNumber(rptAnnualReportEntity.getRegistrationNumber());
        rptMatchingReportEntity.setDomination(rptAnnualReportEntity.getDomination());
        rptMatchingReportEntity.setAddress(rptAnnualReportEntity.getAddress());
        rptMatchingReportEntity.setContactNumber(rptAnnualReportEntity.getContactNumber());
        rptMatchingReportEntity.setEstablishDate(rptAnnualReportEntity.getEstablishDate());
        rptMatchingReportEntity.setApprovalDate(rptAnnualReportEntity.getApprovalDate());
        rptMatchingReportEntity.setEnterpriseStatus(rptAnnualReportEntity.getEnterpriseStatus());
        rptMatchingReportEntity.setLiaisonManName(rptAnnualReportEntity.getLiaisonManName());
        rptMatchingReportEntity.setLiaisonManPhone(rptAnnualReportEntity.getLiaisonManPhone());
        rptMatchingReportEntity.setCreateTime(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
        rptMatchingReportEntity.setReportStatus(rptAnnualReportEntity.getReportStatus());
        rptMatchingReportEntity.setEnterpriseType(rptAnnualReportEntity.getEnterpriseType());
        return rptMatchingReportEntity;
    }

}
